package com.xiaoshuidi.cloud.module.bpm.job.xxljob;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.framework.tenant.core.aop.TenantIgnore;
import com.xiaoshuidi.cloud.framework.tenant.core.job.TenantJob;
import com.xiaoshuidi.cloud.module.bpm.controller.admin.swo.vo.TicketDelayJobParamDTO;
import com.xiaoshuidi.cloud.module.bpm.dal.dataobject.swo.SwoTicketDO;
import com.xiaoshuidi.cloud.module.bpm.dal.mysql.swo.SwoTicketMapper;
import com.xiaoshuidi.cloud.module.bpm.enums.swo.SwoServiceStatusEnum;
import com.xiaoshuidi.cloud.module.bpm.enums.swo.TicketServiceStatusEnum;
import com.xiaoshuidi.cloud.module.bpm.job.delayjob.TicketDelayJobService;
import com.xiaoshuidi.cloud.module.bpm.job.delayjob.TicketDelayJobTypeEnum;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.xiaoshuidi.cloud.module.bpm.enums.ErrorCodeConstants.SWO_TICKET_REQUIRED_COMPLETION_TIME_ERROR;

/**
 * 完工超时提醒
 */

@Slf4j
@Component
public class CompletionTimeoutReminderJob {

    @Resource
    private SwoTicketMapper swoTicketMapper;
    @Resource
    private TicketDelayJobService ticketDelayJobService;

    /**
     * 获取完工时间是当天的服务工单, 放进延迟任务中执行
     */
    @XxlJob("completion_timeout_reminder")
    @TenantIgnore
    public void completionTimeoutReminder() {
        log.info("[完工超时提醒Job] 获取完工时间是当天的服务工单 --- 开始");
        // 工单状态是处理中且完工时间是当天
        LambdaQueryWrapper<SwoTicketDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SwoTicketDO::getStatus, TicketServiceStatusEnum.IN_PROGRESS.getStatus());
        wrapper.between(SwoTicketDO::getRequiredCompletionTime, LocalDateTimeUtil.beginOfDay(LocalDateTime.now()), LocalDateTimeUtil.endOfDay(LocalDateTime.now()));
        List<SwoTicketDO> swoTicketDOS = swoTicketMapper.selectList(wrapper);
        log.info("[完工超时提醒Job] 完工时间是当天的服务工单: {}", JsonUtils.toJsonString(swoTicketDOS));
        for (SwoTicketDO swoTicketDO : swoTicketDOS) {
            log.info("[完工超时提醒Job] 服务工单: {}", JsonUtils.toJsonString(swoTicketDO));
            // 检查是否指定了要求完工时间
            if (ObjectUtil.isNotEmpty(swoTicketDO.getRequiredCompletionTime())) {
                // 完工时间是否在当前时间之前
                LocalDateTime requiredCompletionTime = swoTicketDO.getRequiredCompletionTime();
                // 点前时间和完工时间间隔, 分钟
                long minutes = LocalDateTimeUtil.between(LocalDateTime.now(), requiredCompletionTime).toMinutes();
                // 间隔在两个小时之内, 1分钟后发送短信提醒
                if (minutes <= 120) {
                    minutes = 1L;
                } else {
                    // 间隔在两个小时以上, 计算当前时间和完工时间前两个小时之间的间隔
                    minutes = LocalDateTimeUtil.between(LocalDateTime.now(), requiredCompletionTime.minusHours(2)).toMinutes();
                }
                // 发送延迟消息
                TicketDelayJobParamDTO ticketDelayJobParamDTO = new TicketDelayJobParamDTO();
                ticketDelayJobParamDTO.setSwoTicketId(swoTicketDO.getId());
                ticketDelayJobParamDTO.setAssigneeId(swoTicketDO.getAssignee());
                ticketDelayJobParamDTO.setReminderType(1);
                ticketDelayJobService.addDelayJob(TicketDelayJobTypeEnum.COMPLETION_TIMEOUT_REMINDER, ticketDelayJobParamDTO, minutes, TimeUnit.MINUTES);
                log.info("[完工超时提醒Job] 服务工单: {}, {}分钟后执行任务", swoTicketDO.getId(), minutes);
            }
        }
        log.info("[完工超时提醒Job] 获取完工时间是当天的服务工单 --- 完成");
    }
}
